﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Collections;

namespace HandScreen.DataMining
{
    public class VTRoute
    {
        private String foreground;

        public String Foreground
        {
            get { return foreground; }
            set { foreground = value; }
        }
        private String background;

        public String Background
        {
            get { return background; }
            set { background = value; }
        }
        private String name;

        public String Name
        {
            get { return name; }
            set
            {
                name = value;
                try
                {
                    routeNum = int.Parse(name);
                }
                catch (Exception e)
                {
                    routeNum = 9999;
                }
            }
        }
        private String destination;

        private int routeNum;

        public int RouteNum
        {
          get { return routeNum; }
        }

        public String Destination
        {
            get { return destination; }
            set { destination = value; }
        }
        private String via;

        public String Via
        {
            get { return via; }
            set { via = value; }
        }

        public String NextTrip
        {
            get
            {
                if (nextTime == 99)
                {
                    return "";
                }
                else if (!nextTimeReal)
                {
                    return "ca " + nextTime;
                }
                else if (nextTime == 0)
                {
                    return "Now";
                }
                return "" + nextTime;
            }
        }

        public String NextNextTrip
        {
            get
            {
                if (nextNextTime == 99)
                {
                    return "";
                }
                else if (!nextNextTimeReal)
                {
                    return "ca " + nextNextTime;
                }
                else if (nextNextTime == 0)
                {
                    return "Now";
                }
                return "" + nextNextTime;
            }
        }

        private int nextTime;

        public int NextTime
        {
            get { return nextTime; }
            set { nextTime = value; }
        }
        private Boolean nextTimeReal;

        public Boolean NextTimeReal
        {
            get { return nextTimeReal; }
            set { nextTimeReal = value; }
        }
        private int nextNextTime;

        public int NextNextTime
        {
            get { return nextNextTime; }
            set { nextNextTime = value; }
        }
        private Boolean nextNextTimeReal;

        public Boolean NextNextTimeReal
        {
            get { return nextNextTimeReal; }
            set { nextNextTimeReal = value; }
        }
    }

    public class Vasttrafik
    {
        private static String identifier = "1279cc8c-9143-4821-9f74-c90db367d57d";
        private ArrayList routes;

        public ArrayList Routes
        {
            get { return routes; }
        }

        private String stopID;
        private Boolean sortByDepTime;

        public Vasttrafik(String stopID, Boolean sortByDepTime)
        {
            this.sortByDepTime = sortByDepTime;
            this.stopID = stopID;
        }

        public int update()
        {
            routes = new ArrayList();
            String sURL;
            sURL = "http://vasttrafik.se/External_Services/NextTrip.asmx/GetForecast?identifier=" + identifier + "&stopId=" + stopID;
            
            //Console.WriteLine(sURL); //testprinting

            WebRequest wrGETURL;
            wrGETURL = WebRequest.Create(sURL);

            Stream objStream;
            objStream = wrGETURL.GetResponse().GetResponseStream();

            StreamReader objReader = new StreamReader(objStream);

            String sLine = "";
            String outString = "";
            int i = 0;

            while (sLine != null)
            {
                i++;
                sLine = objReader.ReadLine();
                if (sLine != null)
                {
                    sLine = System.Net.WebUtility.HtmlDecode(sLine);
                    outString = sLine;
                    //Console.WriteLine("{0}:{1}", i, sLine); //testprinting
                }
            }
            outString = outString.Replace("<string xmlns=\"http://vasttrafik.se/\">", "");
            TextReader outPut = new StringReader(outString);
            int result = parseXML(outPut);

            //foreach (VTRoute routePrint in routes) //testprintings
            //{
            //    Console.WriteLine(routePrint.Name + "\t" + routePrint.Destination + " via " + routePrint.Via + "\t" + routePrint.NextTrip + "\t" + routePrint.NextNextTrip);
            //}

            return result;
        }

        private int parseXML(TextReader input)
        {
            try
            {
                VTRoute newRoute = new VTRoute();
                Boolean infoMode = false;

                XmlTextReader reader = new XmlTextReader(input);
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        string strName = reader.Name;
                        if (strName.Equals("free_text"))
                        {
                            infoMode = true;
                        }
                        else if (strName.Equals("item") && !infoMode)
                        {
                            newRoute = new VTRoute();

                            if (reader.HasAttributes)
                            {
                                for (int i = 0; i < reader.AttributeCount; i++)
                                {
                                    reader.MoveToAttribute(i);
                                    Console.WriteLine(reader.Name + ": " + reader.Value);
                                    if (reader.Name.Equals("line_number"))
                                    {
                                        newRoute.Name = reader.Value;
                                    }
                                    else if (reader.Name.Equals("line_number_foreground_color"))
                                    {
                                        newRoute.Foreground = reader.Value;
                                    }
                                    else if (reader.Name.Equals("line_number_background_color"))
                                    {
                                        newRoute.Background = reader.Value;
                                    }
                                    else if (reader.Name.Equals("via"))
                                    {
                                        newRoute.Via = reader.Value;
                                    }
                                    else if (reader.Name.Equals("next_trip"))
                                    {
                                        try
                                        {
                                            newRoute.NextTime = int.Parse(reader.Value);
                                        }
                                        catch(Exception e)
                                        {
                                            newRoute.NextTime = 99;
                                        }
                                    }
                                    else if (reader.Name.Equals("next_quality"))
                                    {
                                        if(reader.Value.Equals("1"))
                                        {
                                            newRoute.NextTimeReal = true;
                                        }
                                        else
                                        {
                                            newRoute.NextTimeReal = false;
                                        }
                                    }
                                    else if (reader.Name.Equals("next_next_trip"))
                                    {
                                        try
                                        {
                                            newRoute.NextNextTime = int.Parse(reader.Value);
                                        }
                                        catch (Exception e)
                                        {
                                            newRoute.NextNextTime = 99;
                                        }
                                    }
                                    else if (reader.Name.Equals("next_next_quality"))
                                    {
                                        if (reader.Value.Equals("1"))
                                        {
                                            newRoute.NextNextTimeReal = true;
                                        }
                                        else
                                        {
                                            newRoute.NextNextTimeReal = false;
                                        }
                                    }
                                }
                            }
                            //routes.Add(newRoute);
                            if (sortByDepTime)
                            {
                                insertByNextTrip(newRoute);
                            }
                            else
                            {
                                insertByRoute(newRoute);
                            }
                        }
                        //Console.WriteLine(strURI,strName,strName,attributes); //testprinting
                    }
                    else if (reader.NodeType == XmlNodeType.CDATA && !infoMode)
                    {
                        //Console.WriteLine(reader.Name + ": " + reader.Value); //testprinting
                        newRoute.Destination = reader.Value;
                        //Console.WriteLine(strURI,strName,strName,attributes); //testprinting
                    }
                }

                return 1;
            }
            catch (XmlException e)
            {
                Console.WriteLine("error occured: " + e.Message);
                return -1;
            }
        }

        private void insertByNextTrip(VTRoute newRoute)
        {
            // Add the new route to the list at its sorted index, sort by route number
            if (newRoute.Name != null)
            {
                if (routes.Count > 0)
                {
                    if (((VTRoute)routes[routes.Count - 1]).NextTime <= newRoute.NextTime)
                    {
                        routes.Add(newRoute);
                    }
                    else
                    {
                        for (int x = 0; x < routes.Count; x++)
                        {
                            if (((VTRoute)routes[x]).NextTime >= newRoute.NextTime)
                            {
                                routes.Insert(x, newRoute);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    routes.Add(newRoute);
                }
            }
        }

        private void insertByRoute(VTRoute newRoute)
        {
            // Add the new route to the list at its sorted index, sort by route number
            if (newRoute.Name != null)
            {
                if (routes.Count > 0)
                {
                    if (newRoute.RouteNum == 9999)
                    {
                        if (((VTRoute)routes[routes.Count - 1]).Name.Equals(newRoute.Name))
                        {
                            routes.Add(newRoute);
                        }
                        else
                        {
                            Boolean inserted = false;
                            for (int x = 0; x < routes.Count; x++)
                            {
                                if (((VTRoute)routes[x]).Name.Equals(newRoute.Name))
                                {
                                    routes.Insert(x, newRoute);
                                    inserted = true;
                                    break;
                                }
                            }
                            if (!inserted)
                            {
                                routes.Add(newRoute);
                            }
                        }
                    }
                    else
                    {
                        if (((VTRoute)routes[routes.Count - 1]).RouteNum <= newRoute.RouteNum)
                        {
                            routes.Add(newRoute);
                        }
                        else
                        {
                            for (int x = 0; x < routes.Count; x++)
                            {
                                if (((VTRoute)routes[x]).RouteNum >= newRoute.RouteNum)
                                {
                                    routes.Insert(x, newRoute);
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    routes.Add(newRoute);
                }
            }
        }
    }
}
